Weak reference、Soft reference 可以用來解決 Memory leak 的問題,當我們用 Weak reference 指向某個物件,GC 在回收時,就會將其回收掉。而 Soft reference 與 Weak reference 的差異在於,被 Soft reference 所參考的物件,要等到記憶體不足時,才會將其回收掉。
不過大部分的情況下,直接使用 Weak reference 可能不是個最佳解法,接著我們也將一一說明。我們在 Memory leak 篇用 Static property 範例來介紹怎麼用 Weak reference 解決 Memory leak。如下程式碼的WeakReference<TextView>,在 TextView 前面加上 WeakReference 代表弱引用就可以解決 Memory leak 的問題。
class MainActivity : AppCompatActivity() {
    companion object {
		//加上WeakReference避免 Memory leak
        private var textView: WeakReference<TextView>? = null
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main7)
		//加上WeakReference
        textView = WeakReference(findViewById(R.id.textView))
    }
}
但最大的問題其實還是 textView 本來就不應該被放到 static property 的,我們應該檢視的是把 TextView 放到了static property。
接著另一個範例,同樣是用 WeakReference 來解決在 Handler 裡參考了 Activity 的問題。
internal class MyHandler(activity: Activity) : Handler() {
    var activityReference: WeakReference<Activity>
    init {
        activityReference = WeakReference(activity)
    }
    override fun handleMessage(msg: Message) {
        super.handleMessage(msg)
        val activity = activityReference.get()
        if (activity != null) {
        }
    }
}
這個範例用了 WeakReference 解決 Memory leak,卻也反應了更明顯的架構問題。例如:
最後,Weak reference 可以用來解決 Memory leak 的問題,但在使用 Weak Reference 之前,請先確認真正造成 Memory leak 的原因是什麼?是否有更好的解決方式來避免 Memory leak。
參考:
https://medium.com/google-developer-experts/weakreference-in-android-dd1e66b9be9d
https://medium.com/google-developer-experts/finally-understanding-how-references-work-in-android-and-java-26a0d9c92f83